package edu.ccut.titan.tag.chart.render;

import java.awt.Color;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.StandardXYToolTipGenerator;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.RegularTimePeriod;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.RectangleInsets;

import edu.ccut.titan.tag.chart.utils.ChartInfo;
import edu.ccut.titan.tag.chart.utils.StringInfo;
import edu.ccut.titan.tag.chart.utils.SubAixs;

/**
 * Created by IntelliJ IDEA. User: Leslie Date: 2005-11-24 Time: 21:42:41
 * Descriptions:
 */
public class TimeSeriesChartRender extends ChartRender {

	private int granularity;
	private Date minimumDate;
	private Date maximumDate;

	public int getGranularity() {
		return granularity;
	}

	public void setGranularity(int granularity) {
		this.granularity = granularity;
	}

	public Date getMinimumDate() {
		return minimumDate;
	}

	public void setMinimumDate(Date minimumDate) {
		this.minimumDate = minimumDate;
	}

	public Date getMaximumDate() {
		return maximumDate;
	}

	public void setMaximumDate(Date maximumDate) {
		this.maximumDate = maximumDate;
	}

	private XYDataset getXYDataset(List<List<?>> datas) {
		TimeSeriesCollection dataset = new TimeSeriesCollection();
		List<TimeSeries> seriesList = new ArrayList<TimeSeries>();

		if (datas != null) {
			for (List<?> data : datas) {
				if (data.size() > 2) {
					String seriesDescription = (String) data.get(1);
					TimeSeries series = null;

					for (TimeSeries timeSeries : seriesList) {
						if (seriesDescription != null
								&& seriesDescription
										.equals(timeSeries.getKey())) {
							series = timeSeries;
						}
					}

					if (series == null) {
						series = new TimeSeries(seriesDescription, data.get(2)
								.getClass());
						seriesList.add(series);
					}

					series.add((RegularTimePeriod) data.get(2), (Number) data
							.get(0));
				}
			}
		}

		for (TimeSeries series : seriesList) {
			if (series.getItemCount() > 0) {
				dataset.addSeries(series);
			}
		}

		dataset.setDomainIsPointsInTime(true);

		return dataset;
	}

	@Override
	protected JFreeChart createChart(ChartInfo chartInfo) {
		JFreeChart chart = ChartFactory.createTimeSeriesChart(chartInfo
				.getTitle(), chartInfo.getCategoryAxisLable(), chartInfo
				.getNumberAxisLable(), this.getXYDataset(chartInfo.getDatas()),
				chartInfo.isLegend(), chartInfo.isTooltips(), chartInfo
						.isUrls());
		return chart;
	}

	protected Plot renderPrivateChart(JFreeChart chart, ChartInfo chartInfo) {
		XYPlot xyplot = (XYPlot) chart.getPlot();
		xyplot.setDomainGridlinePaint(Color.lightGray);
		xyplot.setRangeGridlinePaint(Color.lightGray);

		xyplot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D));
		xyplot.setDomainCrosshairVisible(true);
		xyplot.setRangeCrosshairVisible(true);

		XYItemRenderer xyitemrenderer = xyplot.getRenderer();
		if (xyitemrenderer instanceof XYLineAndShapeRenderer) {
			XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer) xyitemrenderer;
			xylineandshaperenderer.setShapesVisible(true);
			xylineandshaperenderer.setShapesFilled(true);

			showSecondaryAxisValue(xylineandshaperenderer);
		}

		DateAxis dateaxis = (DateAxis) xyplot.getDomainAxis();
		// dateaxis.setDateFormatOverride(new SimpleDateFormat("HH:mm"));
		// dateaxis
		// .setTickUnit(new DateTickUnit(DateTickUnit.MINUTE, granularity));
		dateaxis.setVerticalTickLabels(true);

		List<SubAixs> subAixses = chartInfo.getSubAixses();
		if (subAixses != null && !subAixses.isEmpty()) {
			int i = 1;
			for (SubAixs subAixs : subAixses) {
				this.renderMultiAxisChart(
						this.getXYDataset(subAixs.getDatas()), xyplot, i++,
						subAixs.getName());
			}
//			this.renderMultipleAxisChart(chart);
		}

		return xyplot;
	}

	public void renderPrivateNakedChart(JFreeChart chart, ChartInfo chartInfo) {
		XYPlot xyplot = (XYPlot) renderPrivateChart(chart, chartInfo);
		ValueAxis valueAxis = xyplot.getRangeAxis();
		valueAxis.setVisible(false);
	}

	public XYPlot renderMultipleAxisChart(JFreeChart jFreeChart) {
		jFreeChart.setBackgroundPaint(Color.white);

		XYPlot xyplot = jFreeChart.getXYPlot();
		xyplot.setOrientation(PlotOrientation.VERTICAL);
		xyplot.setBackgroundPaint(Color.white);
		xyplot.setDomainGridlinePaint(Color.lightGray);
		xyplot.setRangeGridlinePaint(Color.lightGray);
		xyplot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D));
		xyplot.getRangeAxis().setFixedDimension(15D);

		XYItemRenderer xyitemrenderer = xyplot.getRenderer();
		xyitemrenderer.setPaint(Color.black);

		return xyplot;
	}

	public void renderMultiAxisChart(XYDataset xyDataset, XYPlot xyPlot, int i,
			String name) {
		if (i == 1) {
			NumberAxis numberaxis = new NumberAxis(name);
			numberaxis.setFixedDimension(10D);
			numberaxis.setAutoRangeIncludesZero(false);
			numberaxis.setLabelPaint(Color.red);
			numberaxis.setTickLabelPaint(Color.red);

			xyPlot.setRangeAxis(1, numberaxis);
//			xyPlot.setRangeAxisLocation(1, AxisLocation.BOTTOM_OR_LEFT);

			xyPlot.setDataset(1, xyDataset);
			xyPlot.mapDatasetToRangeAxis(1, 1);
			XYItemRenderer xyItemRendererOne = new StandardXYItemRenderer();
			xyItemRendererOne.setSeriesPaint(0, Color.red);
			xyPlot.setRenderer(1, xyItemRendererOne);

			showSecondaryAxisValue(xyItemRendererOne);
		} else if (i == 2) {
			NumberAxis numberaxis1 = new NumberAxis(StringInfo.ONE_CALL_RATIO);
			numberaxis1.setLabelPaint(Color.blue);
			numberaxis1.setTickLabelPaint(Color.blue);
			xyPlot.setRangeAxis(2, numberaxis1);

			xyPlot.setDataset(2, xyDataset);
			xyPlot.mapDatasetToRangeAxis(2, 2);
			XYItemRenderer xyItemRendererTwo = new StandardXYItemRenderer();
			xyItemRendererTwo.setSeriesPaint(0, Color.blue);
			xyPlot.setRenderer(2, xyItemRendererTwo);

			showSecondaryAxisValue(xyItemRendererTwo);
		} else {
			NumberAxis numberaxis2 = new NumberAxis(StringInfo.TWO_CALL_RATIO);
			numberaxis2.setLabelPaint(Color.green);
			numberaxis2.setTickLabelPaint(Color.green);
			xyPlot.setRangeAxis(3, numberaxis2);

			xyPlot.setDataset(3, xyDataset);
			xyPlot.mapDatasetToRangeAxis(3, 3);
			XYItemRenderer xyItemRendererThree = new StandardXYItemRenderer();
			xyItemRendererThree.setSeriesPaint(0, Color.green);
			xyPlot.setRenderer(3, xyItemRendererThree);

			showSecondaryAxisValue(xyItemRendererThree);
		}
	}

	private void showSecondaryAxisValue(XYItemRenderer renderer) {
		NumberFormat myFormat = NumberFormat.getNumberInstance();
		myFormat.setMaximumFractionDigits(6);
		SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm");
		// 在StandardXYToolTipGenerator中的字符串可以任意设置，其中
		// n：0—SeriesKey 1—XValue 2—YValue
		renderer.setToolTipGenerator(new StandardXYToolTipGenerator(
				"{0} {1} ֵΪ{2}", dateFormat, myFormat));
	}

	/**
	 * ����ͼƬ���м䲿��
	 * 
	 * @param chartInfo
	 */
	public void renderPrivateNakedDataPart(JFreeChart chart, ChartInfo chartInfo) {
		XYPlot xyPlot = (XYPlot) renderPrivateChart(chart, chartInfo);
		xyPlot.setDomainGridlinesVisible(false);
		xyPlot.setRangeGridlinesVisible(false);
	}

	/**
	 * ��ʾͼƬ���м䲿��
	 * 
	 * @param chartInfo
	 */
	public void renderPrivateShowDataPart(JFreeChart chart, ChartInfo chartInfo) {
		XYPlot xyPlot = (XYPlot) renderPrivateChart(chart, chartInfo);
		xyPlot.setDomainGridlinesVisible(true);
		xyPlot.setRangeGridlinesVisible(true);
	}
}
